package org.piwicode.bywordofmouth;

import com.google.common.collect.ImmutableList;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author pierre
 */
public class Share {

    private static final Logger LOG = Logger.getLogger(Share.class.getName());
    private final Resource resource;
    //
    final AtomicReference<ImmutableList<Directory>> directories;
    final AtomicReference<ImmutableList<Resource>> resources;
    //
    final ConcurrentMap<File, ImmutableList<Hash>> fileHash;
    final transient ConcurrentMap<Hash, Chunk> hashChunk;

    public Share(String nickName) {
        this.directories = new AtomicReference<>(ImmutableList.<Directory>of());
        this.resource = new FileResource(null, nickName, -1, -1);
        this.resources = new AtomicReference<>(ImmutableList.<Resource>of());
        this.fileHash = new ConcurrentHashMap<>();
        this.hashChunk = new ConcurrentHashMap<>();
    }

    List<Resource> resources() {
        return resources.get();
    }

    Set<Hash> chunkHashSet() {
        return null;//chunkHash.keySet();
    }

    Resource rootResource() {
        return resource;
    }

    List<Hash> getHashFor(Resource resource) {
        return fileHash.get(resource.path().toFile());
    }

    byte[] getChunk(Hash hash) {
        final Chunk chunk = hashChunk.get(hash);
        try (final FileInputStream fis = new FileInputStream(chunk.file())) {
            fis.skip(chunk.offset());
            final byte[] buf = new byte[chunk.length()];
            if (fis.read(buf) != chunk.length()) {
                return null;
            }
            return buf;
        } catch (IOException ex) {
            LOG.log(Level.WARNING, "Unable to read the file", ex);
            return null;
        }
    }
}
